package com.koron.css2.common.service;

import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.ObjectUtil;
import com.deepoove.poi.XWPFTemplate;
import com.koron.css2.ApplicationConfig;
import com.koron.css2.ExportDocInterface;
import com.koron.css2.common.dto.DocDto;
import com.koron.css2.common.utils.AsposeLicenseUtil;
import com.koron.css2.common.utils.Word2PdfAsposeUtil;
import com.koron.css2.serviceManage.bean.RequestBean;
import com.koron.css2.serviceManage.bean.UserInfoBean;
import com.koron.util.DBSourceUtils;
import com.koron.util.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.koron.ebs.mybatis.ADOConnection;
import org.koron.ebs.mybatis.SessionFactory;
import org.koron.ebs.mybatis.SqlTask;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.Map;
import java.util.Objects;

@Slf4j
@Service
public abstract class AbstractExportDoc implements ExportDocInterface {



    public abstract DocDto getDocText(SessionFactory factory, UserInfoBean userInfo, RequestBean req);

    @Override
    public void export(HttpServletResponse response, UserInfoBean userInfo, RequestBean requestBean) throws IOException {
        UUID uuid = UUID.randomUUID();
        InputStream resourceAsStream = null;
        OutputStream tempOut = null;
        InputStream docxRead = null;

        try {

            Map<String, Object> map = JsonUtils.objectToPojo(requestBean.getData(), Map.class);
            if (ObjectUtil.isNull(userInfo)) {
                throw new RuntimeException("用户信息为空");
            }
            if (ObjectUtil.isNull(map)) {
                throw new RuntimeException("缺少参数");
            }


            String dbEnv = DBSourceUtils.getDbEnv(userInfo.getCurWaterCode());
            DocDto docText = ADOConnection.runTask(dbEnv, new SqlTask() {
                @Override
                public Object run(SessionFactory sessionFactory) {

                    return getDocText(sessionFactory, userInfo, requestBean);
                }
            }, DocDto.class);
            log.info("获取的doc内容", docText);
            Objects.requireNonNull(docText, "获取doc内容失败");
            //写入模板
            resourceAsStream = AbstractExportDoc.class.getClassLoader().getResourceAsStream("template/doc/" + docText.getTemplate());
            Objects.requireNonNull(resourceAsStream, "读取不到模板信息");
            Map<String, Object> param = docText.getParam();


            XWPFTemplate template = XWPFTemplate.compile(resourceAsStream).render(param);


            File tempDoc = new File(ApplicationConfig.getUploadTempDir() + File.separator + uuid + ".docx");
            tempOut = new FileOutputStream(tempDoc);
            template.write(tempOut);

            tempOut.close();
            tempOut.flush();
            //File tempRead= new File(ApplicationConfig.getUploadTempDir()+ File.separator +uuid+".docx");
            docxRead = new FileInputStream(tempDoc);

            if (!AsposeLicenseUtil.setWordsLicense()) { // 验证License 若不验证则转化出的pdf文档会有水印产生
                String title = docText.getTitle()+".docx";

                title= URLEncoder.encode(title, "UTF-8");
                response.addHeader("content-type", "application/docx");
                response.addHeader("Content-disposition", "attachment;filename=" + title);
//            response.addHeader("Content-Length", String.valueOf(resourceAsStream.));
                ServletOutputStream out = response.getOutputStream();
                template.writeAndClose(out);

                out.close();
                out.flush();
            } else {



                response.addHeader("content-type", "application/pdf");
                response.addHeader("Content-Disposition", "inline");
                ServletOutputStream outputStream = response.getOutputStream();

                Word2PdfAsposeUtil.convert2PdfStream(docxRead,outputStream);



            }
//            IConverter converter = LocalConverter.builder().build();
//           // File tempPdf= new File(ApplicationConfig.getUploadTempDir()+ File.separator +uuid+".pdf");
//            //OutputStream pdfOut=new FileOutputStream(tempPdf);
//            response.addHeader("content-type", "application/pdf");
//            response.addHeader("Content-Disposition", "inline");
//            ServletOutputStream outputStream = response.getOutputStream();
//            converter.convert(docxRead).as(DocumentType.DOC).to(outputStream).as(DocumentType.PDF).execute();
//            docxRead.close();
//            converter.shutDown();

            //writeOut(tempPdf.getAbsolutePath(),response);

        } catch (Exception e) {
            log.error("导出doc失败：{}", e.getMessage());
            log.error(e.getMessage(), e);
        } finally {
            //InputStream resourceAsStream=null;
            //        OutputStream tempOut=null;
            //        InputStream docxRead=null;
            try {
                if (ObjectUtil.isNotNull(resourceAsStream)) resourceAsStream.close();
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
            try {
                if (ObjectUtil.isNotNull(tempOut)) tempOut.close();
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
            try {
                if (ObjectUtil.isNotNull(docxRead)) docxRead.close();
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }

        }

    }

    public static void writeOut(String pdfPath, HttpServletResponse response) {
        try {
            // String pdfPath = "C:\\Users\\HONOR\\Desktop\\TEMP\\e4a2389e-9542-435f-833d-9223715ff51d.pdf";
            //response.setCharacterEncoding("utf-8");
            response.addHeader("content-type", "application/pdf");
            response.addHeader("Content-Disposition", "inline");
            AbstractExportDoc.writeBytes(pdfPath, response.getOutputStream());
            File file = new File(pdfPath);
            if (file.exists()) {
                DataOutputStream temps = new DataOutputStream(response.getOutputStream());
                DataInputStream in = new DataInputStream(new FileInputStream(pdfPath));
                byte[] b = new byte[2048];
                while ((in.read(b)) != -1) {
                    temps.write(b);
                    temps.flush();
                }
                in.close();
                temps.close();
            } else {
                log.error("文件不存在!");
            }
        } catch (Exception e) {
            throw new RuntimeException("写出文件失败");
        }


    }


    /**
     * 输出指定文件的byte数组
     *
     * @param filePath 文件路径
     * @param os       输出流
     * @return
     */
    public static void writeBytes(String filePath, OutputStream os) throws IOException {
        FileInputStream fis = null;
        try {
            File file = new File(filePath);
            if (!file.exists()) {
                throw new FileNotFoundException(filePath);
            }
            fis = new FileInputStream(file);
            byte[] b = new byte[1024];
            int length;
            while ((length = fis.read(b)) > 0) {
                os.write(b, 0, length);
            }
        } catch (IOException e) {
            throw e;
        } finally {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
    }


}

